module vmm

import time

// monitor gc not expect behaivour

__global (
    max_bytes = size_t(0)
    last_gcno = size_t(0)
    gcno_nochg_cnt = int(0)
)

pub fn start_monitor(max_use_bytes int) {
    max_bytes = size_t(max_use_bytes)
    go monitor_proc()
}

fn monitor_proc() {
    mut abcnt := 5
    for {
        ensuresleep(5)
        gcno := C.GC_get_gc_no()
        if gcno == last_gcno {
            gcno_nochg_cnt ++
        }else{
            gcno_nochg_cnt = 0
            last_gcno = gcno
        }

        heapsz := C.GC_get_heap_size()
        if gcno_nochg_cnt > 6 || heapsz > max_bytes {
            gcok := C.GC_is_init_called()
            disabled := C.GC_is_disabled()
            println("GC unexpect after $gcno, heap $heapsz, gcok $gcok, disabled $disabled")
            // C.GC_disable()
            // C.GC_deinit()
            // C.GC_init()
            // C.GC_enable()
            gcollect()
            abcnt--
            if abcnt == 0 {
                //C.abort()
            }
        }
    }
}

fn ensuresleep(n int) {
    btime := time.now()
    for {
        time.sleep(1)
        nowt := time.now()
        if nowt.unix_time() - btime.unix_time() >= n {
            break
        }
    }
}
